package com.gurumades.jsonform.test.dispatch.validators;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.AnnotationIntrospector;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.JsonNodeFactory;
import org.codehaus.jackson.node.ObjectNode;
import org.codehaus.jackson.xc.JaxbAnnotationIntrospector;

import com.google.appengine.repackaged.org.json.JSONObject;
import com.gurumades.jsonform.server.forms.dispatch.ServerSideJsonHelper;
import com.gurumades.jsonform.shared.dispatch.FieldHelper;
import com.gurumades.jsonform.shared.dispatch.validators.ValidatorHelper;

public class FormFixtures {

	private static JsonNode testForm;
	private static JsonParser parser;
	
	private static ObjectMapper mapper = new ObjectMapper();
	
	static {
		ValidatorHelper.setJsonhelper(new ServerSideJsonHelper());
		FieldHelper.setHelper(ValidatorHelper.getJsonHelper());
	}
	static HashMap<String, ObjectNode> formItems = new HashMap<String, ObjectNode>();
	
	public static void loadForm(String formID) throws IOException, JAXBException{
		URL url = ClassLoader.getSystemClassLoader().getResource("com/gurumades/jsonform/test/dispatch/validators/"+formID+".xml");
		InputStream streamResource = url.openStream();

		Unmarshaller marshaler = getUnMarshaller();
		JAXBElement o = (JAXBElement) marshaler
				.unmarshal(new InputStreamReader(streamResource));
		
		ObjectMapper mapper = new ObjectMapper();
        AnnotationIntrospector introspector = new JaxbAnnotationIntrospector();
        mapper.getDeserializationConfig().setAnnotationIntrospector(introspector);
        mapper.getSerializationConfig().setAnnotationIntrospector(introspector);
        
        String jsonString = mapper.defaultPrettyPrintingWriter().writeValueAsString(o.getValue());
        
        ObjectMapper m = new ObjectMapper();
		JsonFactory factory = m.getJsonFactory();
		parser = factory.createJsonParser(new StringReader(jsonString));
		testForm = parser.readValueAsTree();
		
		formItems.clear();
		List<JsonNode> items = testForm.findParents("extra");
		for (JsonNode jsonNode : items) {
			ObjectNode item = (ObjectNode)jsonNode;
			formItems.put(item.path("id").getTextValue(), item);
		}
	}
	
	public static ObjectNode getFormItemWithName(String itemName){
		return formItems.get(itemName);
	}
	
	
	public static Map<String, Object> makeFormItemValue(String fieldName, Object value_) throws JsonProcessingException, IOException{
		Writer strWrit = new StringWriter();
		mapper.defaultPrettyPrintingWriter().writeValue(strWrit, value_);
		
		String serialized = strWrit.toString();
		JsonNode node = mapper.readTree(new StringReader(serialized));
		ObjectNode value = JsonNodeFactory.instance.objectNode();
		value.put("value", node);
		HashMap<String, Object> values = new HashMap<String, Object>();
		values.put(fieldName, value);
		
		return values;
	}
	private static Unmarshaller getUnMarshaller() {
		try {

			JAXBContext cxt = initContext();
			return cxt.createUnmarshaller();
		} catch (JAXBException e) {
			e.printStackTrace();

			return null;
		}
	}

	private static JAXBContext initContext() throws JAXBException {
		JAXBContext cxt = JAXBContext
				.newInstance("com.gurumades.jsonform.server.forms");
		return cxt;
	}
	
}
